package ar.edu.itba.it.cg.grupo01.impl.scene.optimization;

import static com.google.common.base.Preconditions.checkNotNull;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import ar.edu.itba.it.cg.grupo01.api.Intersection;
import ar.edu.itba.it.cg.grupo01.api.Ray;
import ar.edu.itba.it.cg.grupo01.api.shape.Shape;
import ar.edu.itba.it.cg.grupo01.impl.IntersectionFactory;
import ar.edu.itba.it.cg.grupo01.impl.shape.AABB;

class Leaf extends OctNode {
	private List<Shape> shapes;

	Leaf(Collection<? extends Shape> shapes, AABB box,
			IntersectionFactory intersectionFactory) {
		super(box, intersectionFactory);
		checkNotNull(shapes, "Shapes should not be null");
		this.shapes = new ArrayList<Shape>(shapes);
	}

	@Override
	public Intersection<? extends Shape> intersects(Ray ray) {
		Intersection<? extends Shape> intersection = box.intersects(ray);

		if (!intersection.intersects()) {
			return intersection;
		}

		Set<Intersection<? extends Shape>> intersections = new HashSet<Intersection<? extends Shape>>();

		for (Shape shape : shapes) {
			intersections.add(shape.intersects(ray));
		}

		return intersectionFactory.createIntersection(intersections);
	}

	@Override
	public int getDepth() {
		return 1;
	}

	@Override
	int leafAmount() {
		return 1;
	}

	@Override
	public Intersection<? extends Shape> hitsLight(Ray lightRay, Shape shape) {
		Intersection<? extends Shape> intersection = box.intersects(lightRay);

		if (!intersection.intersects()) {
			return intersection;
		}

		Set<Intersection<? extends Shape>> intersections = new HashSet<Intersection<? extends Shape>>();

		for (Shape leafShape : shapes) {
			if( ! leafShape.equals(shape) ) {
				intersections.add(leafShape.intersects(lightRay));
			}
		}

		return intersectionFactory.createIntersection(intersections);
	}

}
